home *** CD-ROM | disk | FTP | other *** search
/ Windows Undocumented File Formats / Windows Undocumented File Formats.img / CHAP10 / LEDUMP.C next >
C/C++ Source or Header  |  1997-07-20  |  8KB  |  320 lines

  1. /**********************************************************************
  2.  *
  3.  * PROGRAM: LEDUMP.C
  4.  *
  5.  * PURPOSE: Dump 'LE' file info
  6.  *
  7.  * Copyright 1997, Mike Wallace and Pete Davis
  8.  *
  9.  * Chapter 10, LE File Format, from Undocumented Windows File Formats,
  10.  * published by R&D Books, an imprint of Miller Freeman, Inc.
  11.  *
  12.  **********************************************************************/
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <malloc.h>
  18. #include <windows.h>
  19. #include "ledump.h"
  20.  
  21. /* Make this big thing global since we'll need it everywhere. */
  22. LEHEADER    LEHeader;
  23. long        LEStart;    /* Keep track of start of LE Header */
  24.  
  25.  
  26. BOOL SkipMZ(FILE *LEFile)
  27. {
  28.     MZHEADER MZHeader;
  29.  
  30.     fread(&MZHeader, sizeof(MZHeader), 1, LEFile);
  31.     if (MZHeader.MZMagic[0] != 'M' || MZHeader.MZMagic[1] != 'Z')
  32.     {
  33.         printf("This is not an executable file!\n");
  34.         return FALSE;
  35.     }
  36.  
  37.     if (!MZHeader.LEOff)
  38.     {
  39.         printf("This is a DOS executable.\n");
  40.         return FALSE;
  41.     }
  42.  
  43.     fseek(LEFile, MZHeader.LEOff, SEEK_SET);
  44.     return TRUE;
  45. }
  46.  
  47. void DumpHeaderInfo()
  48. {
  49.     DWORD Flags;
  50.     
  51.     Flags = LEHeader.ModuleFlags; /* Get it into an easier to type variable */
  52.     
  53.     printf("CPU Required: ");
  54.     switch(LEHeader.CPUType)
  55.     {
  56.         case CPU_286:
  57.             printf("80286\n");
  58.             break;
  59.         case CPU_386:
  60.             printf("80386\n");
  61.             break;
  62.         case CPU_486:
  63.             printf("80486\n");
  64.             break;
  65.     }
  66.     
  67.     printf("OS Required: ");
  68.     switch(LEHeader.OSType)
  69.     {
  70.         case OS_UNKNOWN:
  71.             printf("Unknown\n");
  72.             break;
  73.         case OS_OS2:
  74.             printf("OS/2\n");
  75.             break;
  76.         case OS_WINDOWS:
  77.             printf("Windows\n");
  78.             break;
  79.         case OS_DOS4X:
  80.             printf("DOS 4.x\n");
  81.             break;
  82.         case OS_WINDOWS386:
  83.             printf("Windows 386 Enhanced Mode\n");
  84.             break;
  85.     }
  86.     
  87.     printf("Initial EIP: %lX:%08lX\n", LEHeader.EIPObjNum, LEHeader.EIP);
  88.     printf("Initial ESP: %lX:%08lX\n", LEHeader.ESPObjNum, LEHeader.ESP);
  89.     
  90.     printf("Flags: 0x%08lX\n", Flags);
  91.     if (Flags & MOD_PERPROCESSLIBINIT)
  92.         printf("- Per Process Library Initialization\n");
  93.     if (Flags & MOD_INTERNALFIXUPS)
  94.         printf("- Internal Fixups\n");
  95.     if (Flags & MOD_EXTERNALFIXUPS)
  96.         printf("- External Fixups\n");
  97.     if ( (Flags & MOD_USES_PM) == MOD_USES_PM)
  98.         printf("- Uses Presentation Manager\n");
  99.     else
  100.     {
  101.         if (Flags & MOD_INCOMPAT_PM)
  102.             printf("- Incompatible with Presentation Manager\n");
  103.         if (Flags & MOD_COMPAT_PM)
  104.             printf("- Compatible with Presentation Manager\n");
  105.     }
  106.     if (Flags & MOD_NOTLOADABLE)
  107.         printf("- Module is not loadable.\n");
  108.     if ( (Flags & MOD_PROTLIBMOD) == MOD_PROTLIBMOD)
  109.         printf("- Protected Memory Library Module\n");
  110.     else if ( (Flags & MOD_VIRTDEVICEDRVR) == MOD_VIRTDEVICEDRVR)
  111.         printf("- Virtual Device Driver Module\n");
  112.     else
  113.     {
  114.         if (Flags & MOD_LIBMOD)
  115.             printf("- Library Module\n");
  116.         if (Flags & MOD_PHYSDEVICEDRVR)
  117.             printf("- Physical Device Driver\n");
  118.     }
  119.     if (Flags & MOD_PERPROCLIBTERM)
  120.         printf("- Per-Process Library Termination\n");
  121.         
  122.     printf("\n");
  123. }
  124.  
  125. void DumpObjectTable(FILE *LEFile)
  126. {
  127.     DWORD         i;
  128.     OBJTBLENTRY    ote;
  129.     
  130.     printf("There are %ld objects in the Object Table.\n", LEHeader.NumObjects);
  131.     
  132.     fseek(LEFile, LEStart + LEHeader.ObjTblOffset, SEEK_SET);
  133.     for (i=1; i<=LEHeader.NumObjects; i++)
  134.     {
  135.         fread(&ote, sizeof(ote), 1, LEFile);
  136.         printf("Segment #: %ld  Size: 0x%08lX  Reloc Addr: 0x%08lX   # Pages: %ld\n",
  137.                 i, ote.VirtualSize, ote.RelocBaseAddr, ote.NumPgTblEntries);
  138.         if (i == LEHeader.AutoDSObj)
  139.             printf("Auto Data Segment\n");
  140.         printf("Flags:\n");
  141.         if (ote.ObjectFlags & OBJ_READABLE)
  142.             printf("Readable\n");
  143.         if (ote.ObjectFlags & OBJ_WRITEABLE)
  144.             printf("Writeable\n");
  145.         if (ote.ObjectFlags & OBJ_EXECUTABLE)
  146.             printf("Executable\n");
  147.         if (ote.ObjectFlags & OBJ_RESOURCE)
  148.             printf("Resource\n");
  149.         if (ote.ObjectFlags & OBJ_DISCARDABLE)
  150.             printf("Discardable\n");
  151.         if (ote.ObjectFlags & OBJ_SHARED)
  152.             printf("Shared\n");
  153.         if (ote.ObjectFlags & OBJ_PRELOAD)
  154.             printf("Preload\n");
  155.         if (ote.ObjectFlags & OBJ_INVALID)
  156.             printf("Invalid\n");
  157.         if ( (ote.ObjectFlags & OBJ_RESIDENTCONTIG) == OBJ_RESIDENTCONTIG)
  158.             printf("Resident & Contiguous\n");
  159.         else
  160.         {
  161.             if (ote.ObjectFlags & OBJ_ZEROFILLED)
  162.                 printf("Zero-Filled\n");
  163.             if (ote.ObjectFlags & OBJ_RESIDENT)
  164.                 printf("Resident\n");
  165.         }
  166.         if (ote.ObjectFlags & OBJ_RESERVED)
  167.             printf("Reserved\n");
  168.         if (ote.ObjectFlags & OBJ_1616ALIAS)
  169.             printf("16:16 Alias Required\n");
  170.         if (ote.ObjectFlags & OBJ_BIGDEFAULT)
  171.             printf("'Big' bit for segment descriptor\n");
  172.         if (ote.ObjectFlags & OBJ_CONFORM)
  173.             printf("Object is conforming to code\n");
  174.         if (ote.ObjectFlags & OBJ_PRIVILEGE)
  175.             printf("Object I/O privilege level\n");
  176.         printf("\n");
  177.     }
  178. }
  179.  
  180. void DumpNameTable(FILE *LEFile, DWORD size)
  181. {
  182.     DWORD    Curr;
  183.     BYTE    len;
  184.     char    Name[257];
  185.     WORD    Ord;
  186.     
  187.     Curr = 0;
  188.     while (Curr < size)
  189.     {
  190.         fread(&len, sizeof(len), 1, LEFile);
  191.         Curr += (len + sizeof(len) + sizeof(Ord));
  192.         fread(Name, len, 1, LEFile);
  193.         Name[len] = 0x00;
  194.         fread(&Ord, sizeof(Ord), 1, LEFile);
  195.         printf("%u         %s\n", Ord, Name);
  196.     }
  197.     
  198. }
  199.  
  200. /* Dumps the Resident and Non-Resident Name Tables */
  201. void DumpNameTables(FILE *LEFile)
  202. {
  203.     printf("\nResident Name Table\n");
  204.     printf("Ordinal   Name\n");
  205.     fseek(LEFile, LEStart + LEHeader.ResNameTable, SEEK_SET);
  206.     DumpNameTable(LEFile, (LEHeader.EntryTable - LEHeader.ResNameTable) - 1);
  207.     printf("\n");
  208.     printf("Non-Resident Name Table\n");
  209.     printf("Ordinal   Name\n");
  210.     fseek(LEFile, LEHeader.NonResTable, SEEK_SET);
  211.     DumpNameTable(LEFile, LEHeader.NonResSize - 1);
  212.     
  213. }
  214. /*
  215. void DumpImports(FILE *LEFile)
  216. {
  217.     FIXUPREC    FixupRec;
  218.     PROCBYNAME    ProcByName;
  219.     PROCBYORD    ProcByOrd;
  220.     long        CurrLoc;
  221.     
  222.     fseek(LEFile, LEStart+LEHeader.FixupRecTable, SEEK_SET);
  223.     
  224.  
  225. }
  226. */
  227. void Check4HeaderSurprises()
  228. {
  229.     if (LEHeader.ByteOrder != ORD_LITTLEENDIAN)
  230.         printf("Byte Order is not Little Endian!\n");
  231.     if (LEHeader.WordOrder != ORD_LITTLEENDIAN)
  232.         printf("Word Order is not Little Endian!\n");
  233.     
  234.     if (LEHeader.CPUType < CPU_386)
  235.         printf("Doesn't require a 386 or better!\n");
  236.     if (LEHeader.OSType != OS_WINDOWS386) 
  237.         printf("Not a Windows386 VxD!\n"); 
  238.  
  239.     if (LEHeader.ResourceTbl)
  240.         printf("Resource Table Found!\n");
  241.     if (LEHeader.NumResources)
  242.         printf("Num Resources Found!\n");
  243.     if (LEHeader.ModDirectTable)
  244.         printf("Module Directive Table Found!\n");
  245.     if (LEHeader.NumModDirect)
  246.         printf("NumModDirect Found!\n");
  247.     if (LEHeader.NumInstPreload)
  248.         printf("Instance Preloads Found!\n");
  249.     if (LEHeader.NumInstDemand)
  250.         printf("Instance Demands Found!\n");
  251.     if (LEHeader.FixupChecksum)
  252.         printf("Fixup Checksum Found!\n");
  253.     if (LEHeader.LoaderChecksum)
  254.         printf("Loader Checksum Found!\n");
  255.     if (LEHeader.PerPageChecksum)
  256.         printf("Per-Page Checksum Found!\n");
  257.     if (LEHeader.NonResChecksum)
  258.         printf("Non-Resident Name Table Checksum Found!\n");
  259. }
  260.  
  261. void DumpLEFile(FILE *LEFile)
  262. {
  263.     LEStart = ftell(LEFile);
  264.  
  265.     fread(&LEHeader, sizeof(LEHeader), 1, LEFile);
  266.     if (LEHeader.LEMagic[0] != 'L' || LEHeader.LEMagic[1] != 'E') 
  267.     {
  268.         printf("This is not an 'LE' executable.\n\n");
  269.         return;
  270.     }
  271.     
  272.     DumpHeaderInfo();
  273.     
  274.     Check4HeaderSurprises();
  275.     
  276.     DumpObjectTable(LEFile);
  277.     
  278.     DumpNameTables(LEFile);
  279.  
  280. //    if (LEHeader.NumImports)    
  281. //        DumpImports(LEFile);
  282.  
  283. }
  284.  
  285. void Usage(void)
  286. {
  287.     printf("Usage: LEDump filename[.386]\n\n");
  288. }
  289.  
  290. int main(int argc, char *argv[]) 
  291. {
  292.  
  293.     char     filename[256];
  294.     FILE     *LEFile;
  295.  
  296.     if (argc < 2) {
  297.         Usage();
  298.         return EXIT_FAILURE;
  299.     }
  300.     
  301.     strcpy(filename, argv[1]);
  302.     
  303.     if (!strchr(filename, '.'))
  304.         strcat(filename, ".386");
  305.         
  306.     if ((LEFile = fopen(filename, "rb")) == NULL) {
  307.         printf("%s does not exist!\n", filename);
  308.         return EXIT_FAILURE;
  309.     }
  310.     
  311.     if (SkipMZ(LEFile)) 
  312.     {
  313.         printf("Dumping %s\n", filename);
  314.         DumpLEFile(LEFile);
  315.     }
  316.     fclose(LEFile);
  317.     return EXIT_SUCCESS;
  318. }
  319.  
  320.